package com.chiffoyqc.nbiot;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

/**
 * Created by Administrator on 2018/1/11.
 */
public class ReportProcess {

    private String identifier = "hkc";
    private String msgType = "deviceReq";
    private int hasMore = 0;
    private byte falseMore = 0x00;
    private byte trueMore = 0x01;
    private int errcode = 0;//为 1 表示设备传递上来的数据不符合格式要求。
    private int mid = 0;
    private byte bDeviceReq = 0x00;
//    private byte bDeviceReq1 =0x0F;
    private byte bDeviceRsp = 0x03;

    private byte cmdSetTemperateState = 0;

//    private int temperate ;
    //将接收到的上报数据转化为short[]
    private short[] deviceDatas;
    //将short[] deviceDatas转化为String
    private String deviceDataStr;

    //ming paras
//    private int battery =0;//电池电量
//    private String ledState="Unknown"; //LED状态
//    private int ledBrightness=0;//LED亮度
//    private byte[] array=new byte[200];
//    private int tran_flag=0;//透传标志位
//
//    private int curcharidx = 0;
//    private int curcharroll = 0;
//    private int idxstatus = 0;
//    private int setrollstatus = 0;
//
    private byte noMid = 0x00;
    private byte hasMid = 0x01;
    private boolean isContainMid = false;
//    private int mid = 0;
//    private byte cmdsetidx = 0;
//    private byte cmdsetroll = 0;
    private byte errdata = 0;//为 1 表示设备传递上来的数据不符合格式要求。

    /**
     * @param binaryData 设备发送给平台coap报文的payload部分(req rep发送指令不同)
     *                   本例入参：AA 72 00 00 23
     *                   byte[0]--byte[1]:  AA 72 命令头
     *                   byte[2]:   0x00表示设备上报数据deviceReq，0x01表示bDeviceRsp
     *                   byte[3]:   hasMore: 0x00 --- false
     *                                       0x01 --- true
     *                   byte[4]--byte[5]   携带的mid值
     *                   byte[6]:   temperate 温度值
     * @return
     */
    public ReportProcess(byte[] binaryData) {
        errcode = 0;

        /**命令头*/
        if (binaryData[0] != 0x3D || binaryData[1] != 0x72)
        {
            errdata = 1;
            return ;
        }

        /**
         * @param binaryData 设备发送给平台coap报文的payload部分(req rep发送指令不同)
         *                   本例入参：3D 72 00 00 23
         *                   byte[0]--byte[1]:  3D 72 命令头
         *                   byte[2]:   0x00表示设备上报数据deviceReq，0x01表示bDeviceRsp
         *                   byte[3]:   hasMore: 0x00 --- false
         *                                       0x01 --- true
         *                   byte[4]:   temperate 温度值
         * @return
         */

        /**
         * 设备主动上报
         * */
        if (binaryData[2] == bDeviceReq) {//0x00表示主动上报，0x01表示命令下发,0x02表示对主动上报的应答，0x03表示对命令的应答
            msgType = "deviceReq";
            if(binaryData[3] == falseMore ){
                hasMore = 0;
            }else if(binaryData[3] == trueMore){
                hasMore = 1;
            }else {
                errdata = 1;
                return ;
            }

            deviceDatas = new short[binaryData.length - 7];
            for(int i = 0 ,len = deviceDatas.length ; i < len ; i++){
                deviceDatas[i] = (short) (binaryData[i + 7] & 0xFF);
            }
            deviceDataStr = HexUtils.shortsToHexString(deviceDatas);


        }
        /**
         * @param binaryData 设备发送给平台coap报文的payload部分(req rep发送指令不同)
         *                   本例入参：3D 72 01 00 01 1616 23
         *                   byte[0]--byte[1]:  3D 72 命令头
         *                   byte[2]:   0x00表示设备主动上报数据deviceReq，0x01表示设备对service命令的响应bDeviceRsp
         *                   byte[3]:   hasMore: 0x00 --- false
         *                                       0x01 --- true
         *                   byte[4]:   是否携带mid：0x00 -- false
         *                                           0x01 -- true
         *                   byte[5]--byte[6]   携带的mid值
         *                   byte[7-x]:   deviceData
         * @return
         */

        /**
         * 设备对service命令的回应
         * */
        else if (binaryData[2] == bDeviceRsp) {//0x00表示主动上报，0x01表示命令下发,0x02表示对主动上报的应答，0x03表示对命令的应答
            msgType = "deviceRsp";

            if(binaryData[3] == falseMore ){
                hasMore = 0;
            }else if(binaryData[3] == trueMore){
                hasMore = 1;
            }else {
                errdata = 1;
                return ;
            }

            if(binaryData[4] == hasMid ){
                String midStr = Utilty.parseByte2HexStr(new byte[]{binaryData[5],binaryData[6]});
                mid = Integer.valueOf(midStr,16);
                isContainMid = true;

                deviceDatas = new short[binaryData.length - 7];
                for(int i = 0 ,len = deviceDatas.length ; i < len ; i++){
                    deviceDatas[i] = (short) (binaryData[i + 7] & 0xFF);
                }
                deviceDataStr = HexUtils.shortsToHexString(deviceDatas);
            }else if(binaryData[4] == noMid){
                deviceDatas = new short[binaryData.length - 5];
                for(int i = 0 ,len = deviceDatas.length ; i < len ; i++){
                    deviceDatas[i] = (short) (binaryData[i + 5] & 0xFF);
                }
                deviceDataStr = HexUtils.shortsToHexString(deviceDatas);
            }else {
                errdata = 1;
                return;
            }

//            temperate = (int)binaryData[7];



        } else {
            errdata = 1;
            return;
        }


    }

    @SuppressWarnings("deprecation")
    public ObjectNode toJsonNode() {
        try {
            //组装body体
            ObjectMapper mapper = new ObjectMapper();
            ObjectNode root = mapper.createObjectNode();

            //这里我们为了跟文档描述的一致，只有device主动上报的数据才带identifier
            //命令处理结果反馈不带identifier
            root.put("identifier", this.identifier);
            root.put("msgType", this.msgType);

            //根据msgType字段组装消息体
            if (this.msgType.equalsIgnoreCase("deviceReq")) {
                root.put("hasMore", this.hasMore);
                ArrayNode arrynode = mapper.createArrayNode();

                ObjectNode ldecharnode = mapper.createObjectNode();
                ldecharnode.put("serviceId", "DeviceData");
                ObjectNode deviceData = mapper.createObjectNode();
                deviceData.put("deviceData", this.deviceDataStr);
                deviceData.put("msgType", this.msgType);
                ldecharnode.set("serviceData", deviceData);
                arrynode.add(ldecharnode);

                root.set("data", arrynode);

            } else if(this.msgType.equalsIgnoreCase("deviceRsp")) {
                /**
                 * 此处是设备对service命令的回复
                 * */
                root.put("errcode", this.errcode);
                root.put("hasMore",this.hasMore);
                //此处需要考虑兼容性，如果没有传mid，则不对其进行解码
                if (isContainMid) {
                    root.put("mid", this.mid);//mid
                }
                //组装body体，只能为ObjectNode对象
                ObjectNode body = mapper.createObjectNode();
                body.put("deviceData", this.deviceDataStr);
                body.put("msgType", this.msgType);
                root.set("body", body);
            } else {
                return null;
            }
//           }
            return root;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}
